package com.yami.shop.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yami.shop.bean.dto.SkuStockLockDTO;
import com.yami.shop.bean.enums.EsOperationType;
import com.yami.shop.bean.enums.StockBillType;
import com.yami.shop.bean.enums.StockType;
import com.yami.shop.bean.event.EsProductUpdateEvent;
import com.yami.shop.bean.event.ProdStockChangeStatusEvent;
import com.yami.shop.bean.model.Order;
import com.yami.shop.bean.model.Sku;
import com.yami.shop.bean.model.SkuStock;
import com.yami.shop.bean.model.SkuStockLock;
import com.yami.shop.common.exception.YamiShopBindException;
import com.yami.shop.common.response.ResponseEnum;
import com.yami.shop.common.response.ServerResponseEntity;
import com.yami.shop.dao.ProdExtensionMapper;
import com.yami.shop.dao.SkuStockLockMapper;
import com.yami.shop.dao.SkuStockMapper;
import com.yami.shop.service.ProdExtensionService;
import com.yami.shop.service.SkuService;
import com.yami.shop.service.SkuStockLockService;
import com.yami.shop.service.StockBillLogService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 库存锁定信息
 *
 * @author lhd
 * @date 2022-05-06 17:27:53
 */
@Service
public class SkuStockLockServiceImpl extends ServiceImpl<SkuStockLockMapper, SkuStockLock> implements SkuStockLockService {

    @Autowired
    private SkuStockLockMapper skuStockLockMapper;
    @Autowired
    private ProdExtensionMapper prodExtensionMapper;
    @Autowired
    private StockBillLogService stockBillLogService;
    @Autowired
    private SkuStockMapper skuStockMapper;
    @Autowired
    private SkuService skuService;
    @Autowired
    private ProdExtensionService prodExtensionService;
    @Autowired
    private ApplicationEventPublisher eventPublisher;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ServerResponseEntity<?> lock(List<SkuStockLockDTO> skuStockLocksParam, List<Order> orders) {
        List<SkuStockLock> skuStockLocks = new ArrayList<>();
        for (SkuStockLockDTO skuStockLockDTO : skuStockLocksParam) {
            SkuStockLock skuStockLock = new SkuStockLock();
            skuStockLock.setCount(skuStockLockDTO.getCount());
            skuStockLock.setOrderNumber(skuStockLockDTO.getOrderNumber());
            skuStockLock.setSkuId(skuStockLockDTO.getSkuId());
            skuStockLock.setProdId(skuStockLockDTO.getProdId());
            skuStockLock.setStatus(0);
            skuStockLocks.add(skuStockLock);

            // 减sku库存
            int skuStockUpdateIsSuccess = skuStockMapper.reduceStockByOrder(skuStockLockDTO.getSkuId(), skuStockLockDTO.getCount());
            if (skuStockUpdateIsSuccess < 1) {
                return ServerResponseEntity.fail(ResponseEnum.NOT_STOCK, skuStockLockDTO.getSkuId());
            }

            // 减商品库存
            int spuStockUpdateIsSuccess = prodExtensionMapper.reduceStockByOrder(skuStockLockDTO.getProdId(), skuStockLockDTO.getCount());
            if (spuStockUpdateIsSuccess < 1) {
                return ServerResponseEntity.fail(ResponseEnum.NOT_STOCK, skuStockLockDTO.getSkuId());
            }
        }

        // 保存库存锁定信息
        skuStockLockMapper.saveBatch(skuStockLocks);

        if (ObjectUtil.isNotNull(orders) && !orders.isEmpty()) {
            // 生成出库明细
            stockBillLogService.generateStockLogOfOrderList(orders, StockBillType.PURCHASE_OUTBOUND.value(), StockType.OUT_OF_STOCK.value());
        }
//        List<String> orderIds = skuStockLocksParam.stream().map(SkuStockLockDTO::getOrderNumber).collect(Collectors.toList());
//
//        // 一个小时后解锁库存
//        SendStatus sendStatus = stockMqTemplate.syncSend(RocketMqConstant.STOCK_UNLOCK_TOPIC, new GenericMessage<>(orderIds), RocketMqConstant.TIMEOUT, RocketMqConstant.CANCEL_ORDER_DELAY_LEVEL + 1).getSendStatus();
//        if (!Objects.equals(sendStatus,SendStatus.SEND_OK)) {
//            // 消息发不出去就抛异常，发的出去无所谓
//            throw new YamiShopBindException(ResponseEnum.EXCEPTION);
//        }
//        System.out.println("222:" + System.currentTimeMillis());

        return ServerResponseEntity.success();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void unlockStock(List<Order> orders) {
//        List<Order> orderList = orderService.getOrdersStatus(orderNumbers);
//        List<String> needUnLockOrderIds = new ArrayList<>();
//        for (Order orderStatusBO : orderList) {
//            // 该订单没有下单成功，或订单已取消，赶紧解锁库存
//            if (orderStatusBO.getStatus() == null || Objects.equals(orderStatusBO.getStatus(), OrderStatus.CLOSE.value())) {
//                needUnLockOrderIds.add(orderStatusBO.getOrderNumber());
//            }
//        }
//
//        if (CollectionUtil.isEmpty(needUnLockOrderIds)) {
//            return;
//        }
        List<String> orderNumber = orders.stream().map(Order::getOrderNumber).collect(Collectors.toList());
        List<SkuStockLock> allSkuWithStocks = list(new LambdaQueryWrapper<SkuStockLock>().in(SkuStockLock::getOrderNumber, orderNumber).eq(SkuStockLock::getStatus, 0));
        if (CollectionUtil.isEmpty(allSkuWithStocks)) {
            return;
        }
        List<Long> lockIds = allSkuWithStocks.stream().map(SkuStockLock::getId).collect(Collectors.toList());
        List<Long> prodIds = allSkuWithStocks.stream().map(SkuStockLock::getProdId).collect(Collectors.toList());
        List<Long> skuIds = allSkuWithStocks.stream().map(SkuStockLock::getSkuId).collect(Collectors.toList());

        // 还原商品库存
        prodExtensionMapper.addStockByOrder(allSkuWithStocks);
        // 还原sku库存
        skuStockMapper.addStockByOrder(allSkuWithStocks);
        // 将锁定状态标记为已解锁
        int updateStatus = skuStockLockMapper.unLockByIds(lockIds);
        for (SkuStockLock allSkuWithStock : allSkuWithStocks) {
            skuService.removeSkuStockCache(allSkuWithStock.getSkuId(), allSkuWithStock.getProdId());
            prodExtensionService.removeProdExtensionCache(allSkuWithStock.getProdId());
        }
        // 更新es中的商品库存
        try {
            eventPublisher.publishEvent(new EsProductUpdateEvent(null, new ArrayList<>(prodIds), EsOperationType.UPDATE_SOLD_NUM_BATCH));
        } catch (Exception e) {
            log.error("取消订单-更新es商品库存失败，错误为：{}", e);
        }
        List<Order> list = orders;
        List<Sku> deleteSkus = skuService.list(new LambdaQueryWrapper<Sku>().select(Sku::getSkuId).in(Sku::getSkuId, skuIds).eq(Sku::getIsDelete, 1));
        List<Long> deleteSkuIds = deleteSkus.stream().map(Sku::getSkuId).collect(Collectors.toList());

        // 移除sku已经删除的订单项
        if (CollUtil.isNotEmpty(deleteSkuIds)) {
            list = new ArrayList<>(orders);
            list.removeIf(order -> {
                order.getOrderItems().removeIf(orderItem -> deleteSkuIds.contains(orderItem.getSkuId()));
                // 订单项全部删除的订单也要删除
                if (CollUtil.isEmpty(order.getOrderItems())) {
                    return Boolean.TRUE;
                }
                return Boolean.FALSE;
            });
        }
        // 生成出入库明细信息
        stockBillLogService.generateStockLogOfOrderList(list, StockBillType.ORDER_CANCEL.value(), StockType.WAREHOUSING.value());

        if (updateStatus == 0) {
            throw new YamiShopBindException(ResponseEnum.EXCEPTION);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void markerStockUse(List<String> orderNumbers) {

        List<SkuStockLock> skuWithStocks = skuStockLockMapper.selectList(new LambdaQueryWrapper<SkuStockLock>().in(SkuStockLock::getOrderNumber, orderNumbers).eq(SkuStockLock::getStatus, 0));

        //  ==============订单从正常状态变成已支付=============
        if (CollectionUtil.isNotEmpty(skuWithStocks)) {
            // 减少商品实际库存，增加销量
            prodExtensionMapper.reduceActualStockByOrder(skuWithStocks);
            // 减少sku实际库存
            skuStockMapper.reduceActualStockByOrder(skuWithStocks);

            // 实际库存为0时，修改商品状态为已售罄
            for (SkuStockLock stocks : skuWithStocks) {
                eventPublisher.publishEvent(new ProdStockChangeStatusEvent(stocks.getProdId(), stocks.getSkuId()));
            }

            int updateStatus = skuStockLockMapper.markerStockUse(orderNumbers, 0);
            if (updateStatus == 0) {
                throw new YamiShopBindException(ResponseEnum.EXCEPTION);
            }
        }
        // 通知商品信息 修改商品状态

    }

    @Override
    public void openBoxMarkerStockUse(Long prodId, Integer num) {
        // 减少商品锁定库存，增加销量
        prodExtensionMapper.reduceLockStockByProdId(prodId, num);
        // 减少sku锁定库存
        List<SkuStock> skuStocks = skuStockMapper.listByProdId(prodId);
        skuStockMapper.reduceLockStockBySkuId(skuStocks.get(0).getSkuId(), num);
    }
}
